package com.hong.spring.sepl;

import com.hong.spring.common.entity.SpElUser;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.*;

/**
 * @Auther: csh
 * @Date: 2020/7/13 15:53
 * @Description:本示例演示了如何使用SpEL表达式将文本字面值解析为相应的数据类型。
 * 数据类型支持负数、小数、科学计数法及八进制、十六进制数等。默认情况下采用Double.parseDouble）方法进行数值转换。
 */
public class PropertyExprSample {
    public static void main(String[] args) {
        //创建对象
        SpElUser user = new SpElUser("hong",29);
        //构建spel解析上下文
        ExpressionParser parser = new SpelExpressionParser();
        EvaluationContext context = new StandardEvaluationContext(user);
        //获取基本属性值
        String username = (String)parser.parseExpression("userName").getValue(context);
        Integer age = (Integer)parser.parseExpression("age").getValue(context);
        System.out.println(username);
        System.out.println(age);


        //数组
        //注：不支持多维数据初始化，会报错！
        int[]arrayl=(int[])parser.parseExpression("new int[]{1,2,3}").getValue(context);
        int[][]array2=(int[][])parser.parseExpression("new int[2][3]").getValue(context);
        System.out.println(arrayl);
        System.out.println(array2);

        //list的解析
        List list=(List) parser. parseExpression("{1,2,3,4}"). getValue(context);
        List listofLists=(List) parser. parseExpression("{{'a','b'},{'x','y'}}"). getValue(context);
        System.out.println(list);
        System.out.println(listofLists);

        //map列表字符串解析
        Map userInfo=(Map)parser.parseExpression("{userName:'hong',credits:100}").getValue(context);
        List userInfo2=(List)parser.parseExpression("{{userName:'hong',credits:100}, {userName:'tom',credits:100}}").getValue(context);
        System.out.println(userInfo);
        System.out.println(userInfo2);

        //从数组,List,Map中较值
//        String interest1= (String)parser.parseExpression("list[0]").getValue(context);
//        String interest2= (String)parser.parseExpression("listofLists[0]").getValue(context);
//        String interest3= (String)parser.parseExpression("interestsMap I'interest1']").getValue(context);
//        System.out.println(interest1);
//        System.out.println(interest2);
//        System.out.println(interest3);

        //方法解析
        String substring=parser.parseExpression("'Spring SpEL'.substring(7)").getValue(String.class);
        Integer index=parser.parseExpression("'Spring SpEL'.indexOf('SpEL')").getValue(Integer.class);
        System.out.println(substring);
        System.out.println(index);
        //调用实例方法
        boolean iscorrect=parser.parseExpression("viladUsername('123456')").getValue(context,Boolean.class);
        System.out.println("iscorrect:"+iscorrect);
        //调用私有方法,将发生错误
//        iscorrect=parser.parseExpression("viladUsername2('hong')").getValue(context,Boolean.class);
//        System.out.println("iscorrect:"+iscorrect);
        //调用静态方法
        iscorrect=parser.parseExpression("viladUsername3('123456')").getValue(context,Boolean.class);
        System.out.println("iscorrect:"+iscorrect);


        //关系操作符
        boolean trueValue=parser. parseExpression("2==2"). getValue(Boolean. class);
        boolean falseValue=parser. parseExpression("2<-5.0"). getValue(Boolean. class);
        System.out.println(trueValue);
        System.out.println(falseValue);
        //字符串关系比较
        trueValue=parser. parseExpression("\"black\"< \"block\""). getValue(Boolean. class);
        System.out.println(trueValue);
        //instanceOf运算符
        falseValue=parser.parseExpression("' xyz' instanceof T(int)"). getValue(Boolean. class);
        System.out.println(falseValue);
        falseValue=parser.parseExpression(" new java.lang.Integer(1) instanceof T(java.lang.Integer)"). getValue(Boolean. class);
        System.out.println(falseValue);
        //正则运算
        trueValue=parser. parseExpression("'15.00' matches '-?\\d+(\\.\\d{2})?$'"). getValue(Boolean. class);
        System.out.println("正则"+trueValue);
        falseValue=parser. parseExpression("'5.0067' matches '\\^-?\\d+(\\.\\d{2})?$'"). getValue(Boolean. class);
        System.out.println("正则"+falseValue);
        //逻辑操作符 and或&& or或|| !
        falseValue=parser.parseExpression("true&&false").getValue(Boolean.class);
        System.out.println("逻辑判断:"+falseValue);
        String expression ="viladUsername('hong') && viladUsername('hong2')";
        Boolean value = parser.parseExpression(expression).getValue(context, Boolean.class);
        System.out.println("逻辑判断:"+value);
        //或判断
        Boolean orVaild = parser.parseExpression("true or false").getValue(Boolean.class);
        System.out.println("或判断:"+orVaild);
        //非判断
        falseValue = parser.parseExpression("!true").getValue(Boolean.class);
        System.out.println("非判断:"+falseValue);
        //算术运算符 % ^
        Integer add = parser.parseExpression("1+1").getValue(Integer.class);
        System.out.println("加法:"+add);
        //String拼接 结果:teststring
        String testString=parser. parseExpression("\"test\"+''+\"string\""). getValue(String. class);
        System.out.println(testString);
        //减法操作,运行结果等于4
        int four=parser.parseExpression("1 - -3").getValue(Integer.class);
        System.out.println("减法运算符:"+four);
        //减法操作,运行结果等于-9000
        double subtraction=parser.parseExpression("1000.00-1e4").getValue(Double.class);
        System.out.println("减法操作:"+subtraction);
        //乘法操作
        int six = parser.parseExpression("-2 * -3").getValue(Integer.class);
        System.out.println("乘法结果:"+six);
        Double twentFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class);
        System.out.println("double结果："+twentFour);
        //除法操作
        double one = parser.parseExpression("8.0/ 4e0 /2").getValue(Double.class);
        System.out.println("除法操作"+one);
        //求余操作
        one = parser.parseExpression("8 / 5 % 2").getValue(Integer.class);
        System.out.println("求余操作:"+one);
        //运算符优先计算操作
        int minusTwentOne = parser.parseExpression("1+2-3*8").getValue(Integer.class);
        System.out.println("运算符优先计算操作:"+minusTwentOne);
        //三元表达式
        expression = " 1==1?true:false";
        Boolean credits = parser.parseExpression(expression).getValue(Boolean.class);
        System.out.println("三元表达式:"+credits);
        //赋值
        parser.parseExpression("userName").setValue(context,"xxxxxxxx");
        System.out.println(user.getUserName());
        //通过表达式赋值
        parser.parseExpression("userName='hong22222222222'").getValue(context);
        System.out.println(user.getUserName());
        //类型
        Class StringClass = parser.parseExpression("T(java.lang.String)").getValue(Class.class);
        System.out.println("判断是否是String,结果是:"+(StringClass==java.lang.String.class));
        Class userClass = parser.parseExpression("T(com.hong.spring.common.entity.SpElUser)").getValue(Class.class);
        System.out.println("用户的类结果是："+(userClass==com.hong.spring.common.entity.SpElUser.class));
        //变量
        context.setVariable("newUserName","hong2222");
            //赋值
        parser.parseExpression("userName=#newUserName").getValue(context);
        System.out.println("赋值后的结果是:"+user.getUserName());
        //this变量值使用 通过 #xx 来获取
        List<Integer> credisList = new ArrayList <Integer>();
        credisList.addAll(Arrays.asList(150,100,30,111,170,33));
        context.setVariable("creadis",credisList);
        List<Integer> conditionResultLit = (List<Integer>)parser.parseExpression("#creadis.?[#this>100]").getValue(context);
        System.out.println("获取大于100的结果"+conditionResultLit);
        List<Boolean> conditionResultBl = (List<Boolean>)parser.parseExpression("#creadis.![#this>100]").getValue(context);
        System.out.println("获取布尔结果："+conditionResultBl);
        //售合过滤
        Map<String,Integer> createsMap = new HashMap <String, Integer>();
        createsMap.put("hong",95);
        createsMap.put("song",110);
        createsMap.put("wiki",99);
        createsMap.put("clean",73);
        createsMap.put("arry",170);
        createsMap.put("test2",204);
        context.setVariable("creadisMap",createsMap);
        Map<Integer,String> conditionMap = (Map<Integer,String>)parser.parseExpression("#creadisMap.?[value>100]").getValue(context);
        System.out.println("获取大于100的Map结果:"+conditionMap);


    }
}
